/**
 * 
 */
package cii_functions;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cii_lib.CCII_ACCESS_INTERF;
import cii_lib.CCII_COMPONENT;

import componentEnhancement.ContextUtils;

/**
 * @author pdrabik
 *
 */
public class FCII_TRANSCEIVER {
	
	private static final Logger log = LoggerFactory
			.getLogger(FCII_TRANSCEIVER.class);

	CCII_COMPONENT sender, receiver;

	public enum TEST_MODE { STATIC, RANDOM }
	/**
	 * @param sender
	 * @param receiver
	 */
	public FCII_TRANSCEIVER(CCII_COMPONENT sender, CCII_COMPONENT receiver) {
		this.sender = sender;
		this.receiver = receiver;
	}
	
	public void calibrate(TEST_MODE tm) {
		calibrate(this.sender, this.receiver, tm);
	}
	
	public int calibrate(CCII_COMPONENT sender, CCII_COMPONENT receiver, TEST_MODE tm) { 
		log.info("sender: {} receiver: {} tm: {}", new Object[] {sender, receiver, tm});
		CCII_ACCESS_INTERF send,rece = null;
		long rSend, rRece;
		long testTime1L = 2000;
		long interval = 200;
		int range=4;
		boolean forceSwaping=true;
		
		CCII_COMPONENT sndComp,rcvComp,demux;
			try {
				//proper interfaces initiate
				sndComp= ContextUtils.getChildByName(sender, "COMP_SEND");
				send =ContextUtils.getInterfByName(sndComp, "WORD_TEST_DATA");
				rcvComp= ContextUtils.getChildByName(receiver, "COMP_REC");
				rece =ContextUtils.getInterfByName(rcvComp, "WORD_TEST_DATA");
				demux = ContextUtils.getChildByName(receiver, "COMP_DEMUX");
				//set static status mode
				ContextUtils.getInterfByName(sndComp,"BITS_TEST_ENA").writeSimple(1);
				ContextUtils.getInterfByName(rcvComp,"BITS_TEST_ENA").writeSimple(1);
			if (tm.equals(TEST_MODE.STATIC)) {
				ContextUtils.getInterfByName(sndComp,"BITS_TEST_RAND_ENA").writeSimple(0);
				ContextUtils.getInterfByName(rcvComp,"BITS_TEST_RAND_ENA").writeSimple(0);
			} else if (tm.equals(TEST_MODE.RANDOM)) {
				ContextUtils.getInterfByName(sndComp,"BITS_TEST_RAND_ENA").writeSimple(1);
				ContextUtils.getInterfByName(rcvComp,"BITS_TEST_RAND_ENA").writeSimple(1);
			}
				//calibrating rutine static test
				for (int t=0;t<range;t++) {
				long start = System.currentTimeMillis();
				long i=start;
				int localErrors=0;
				ContextUtils.getInterfByName(demux,"BITS_DATA_DELAY").writeSimple(t);
				while (i<start+testTime1L) {
					rSend= send.readSimple();
					rRece =rece.readSimple();
				if (tm.equals(TEST_MODE.STATIC)) {	
					if (rSend!=rRece) localErrors++;
				} else if (tm.equals(TEST_MODE.RANDOM)) {
					if (rRece!=0) localErrors++;
				}
					log.debug(i+" calibr/values for param: "+t+" ["+rSend+","+rRece+"]");
					java.lang.Thread.sleep(interval);
					i = System.currentTimeMillis();
					}
				if (localErrors==0) {
					log.debug("Calibration success: param: " + t);
					if (!forceSwaping) {
						log.debug("Result: {}", Integer.toString(t));
						return t;
					}
				}
				else {
					if (t==range-1) log.debug("Calibration unsuccessful");
					else 
						log.debug("Unsuccessful for "+t);
					}
				}
			} catch (Exception e) {
				log.error("", e);
			}
		log.debug("Result: {}", new Integer(-1));
		return -1;
	}
	
	
}
